#include <iostream>
#include <map>
#include <list>

#include "Base.h"
#include "Person.h"
#include "Random.h"
#include "Pointer.h"

//boost
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "boost/thread.hpp"
#include "boost/log/trivial.hpp"


#include "outstrm.h"

using namespace std;

using namespace boost;


void boost_println(int i, int j) {
    std::cout << i + j << std::endl;
}


void boost_println_0(int i) {
    std::cout << i << std::endl;
}

/**
 *
 */
int boost_compare(int a, int b) {
    return a > b;// first in head
}

void boost_ref(int i, outstrm &outstrm1) {
    std::cout << i << std::endl;
//    outstrm1.show(i);
}


/**
 *
 */
void _sleep(long time) {
    boost::this_thread::sleep(boost::posix_time::seconds(time));
}

/**
 * thread test
 */
void runnable() {

    //当前cpu个数
    int cpu_num = boost::thread::hardware_concurrency();
    std::cout << "thread ID: " << boost::this_thread::get_id() << std::endl;
    printf("current cpu num:%d\n", cpu_num);


    try {
        for (int i = 6; i < 7; ++i) {
            _sleep(1);
            std::cout << i << std::endl;
        }
    }
    catch (boost::thread_interrupted &e) {
    }
    for (int i = 0; i < 5; ++i) {
        _sleep(i);
        std::cout << i << std::endl;

    }

}


bool syn = true;
boost::mutex _lock;

/**
 * 多线程  互斥 同步处理
 */
void synWork(int arg, int arg1) {
    for (int i = 0; i < 5; ++i) {
        _sleep(3);

        if (syn) {
            //调用构造函数和析构函数 进行 lock ,unlock
//            boost::lock_guard<boost::mutex> lock(_lock);
            _lock.lock();
            std::cout << "current thread: " << boost::this_thread::get_id() << endl;
            printf("print value:%d arg:%d arg1:%d \n", i, arg, arg1);
            _lock.unlock();
        } else {
            std::cout << "current thread: " << boost::this_thread::get_id() << endl;
            printf("print value:%d arg:%d arg1:%d \n", i, arg, arg1);
        }

    }
}


//////////////////////////////////////

#include "ThreadPool.h"

#include <stdio.h>


void test_file() {

    FILE *file;
    char *file_path = (char *) "myfile.txt";
    file = fopen(file_path, "r");
    if (file == nullptr) {
        printf("not found file:%s\n", file_path);
        return;
    }


    char buffer[1024];
    char *i = new char[1024];
    while (feof(file) != EOF) {
        //max read
        if ((fgets(i, 1024, file) == NULL))break;
        printf("value:%s\n", i);
    }


    //write in stdout
    puts(i);

    FILE *_file = fopen(file_path, "a");
    fputs("写入文件xx", _file);
    fclose(_file);

    FILE *___file = fopen(file_path, "r");
    bzero(i, sizeof(i));
    while (feof(___file) != EOF) {
        //max read
        if ((fgets(i, 1024, ___file) == NULL))break;
    }
    puts(i);
    delete i;

    fclose(___file);
    fclose(file);

}


#include <string>

void test_string() {

    char *txt = (char *) "测试啊啊啊";

    size_t _size = sizeof(txt);
    char buffer[_size];
    memcpy(buffer, txt, _size);

    //println
    puts(buffer);
}


#include "boost/shared_ptr.hpp"
#include <assert.h>

using namespace boost;

void test_share_ptr() {
    //
    boost::shared_ptr<int> sp0(new int(10));
    assert(sp0.unique());
    boost::shared_ptr<int> sp1 = sp0;//copy
    assert(*sp0 == 10
           && sp1 == sp0);
    *sp1 = 1000;

    assert(*sp0 == 1000 && sp1 == sp0);

    //停止shared_ptr的使用
//    sp1.reset();
    sp0.reset();
    assert(!sp0);
    printf("ok \n");
}


#include "outstrm.h"

#include "boost/function.hpp"


/**
 *  测试 boost test function
 */
void test_boost_function() {
    //定义一个f的函数指针 并指向 std::atoi
    typedef boost::function<int(const char *)> f;
    f _f = std::atoi;
    std::cout << _f("1609") << std::endl;
    _f = std::strlen;// reset function
    std::cout << _f("1609") << std::endl;

    boost::function<void()> share_ptr_function = test_share_ptr;
    share_ptr_function();

}

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <arpa/inet.h>

void test_host_by_name() {
    struct hostent *h;
    char hostname[40];
    memset(hostname, 0, 40);
    printf("请输入域名\n");
    scanf("%s", hostname);//wait iputstream
    getchar();
    if ((h = gethostbyname(hostname)) == NULL) {
        fprintf(stderr, "不能得到IP\n");
        exit(1);
    }
    printf("HostName :%s\n", h->h_name);
    printf("IP Address :%s\n", inet_ntoa(*((struct in_addr *) h->h_addr)));
}

#include "A.h"

#include <arpa/inet.h>

/**
 *
 */
int main() {


    //h->n
    unsigned int _n_v = htonl(120);
    unsigned int _h_v=ntohl(2013265920);


    B *_b = new B;
    A *_a = new A(_b);
    A::show(nullptr);
    pthread_t _self = pthread_self();

    pthread_create(&_self, nullptr, &A::show, nullptr);
    pthread_join(_self, nullptr);

    delete _a;


    test_host_by_name();

    //test_boost_function
    test_boost_function();


//test pthread
    outstrm *_o = new outstrm;
    _o->test_pthread();
    delete _o;


    //test share_prt
//    test_share_ptr();



//    test_string();
//
//    test_file();
    //boost thread
//    boost::thread _test_thread(runnable);//start and excutor the call method
//    _test_thread.interrupt();//
//    _test_thread.join();// hold the current thread, until the boost_println_0 method be done!

    boost::thread t1(boost::bind(synWork, 100, 190));
    boost::thread t2(boost::bind(synWork, 100, 5639));
    t1.join();
    t2.join();

    //
//    boost::thread t3(boost::bind(&Person::kk, 100));
//    t3.join();



    //thread pool test
//    progschj::ThreadPool pool;
//
//    std::vector<std::future<int> > results;
//    for(int i = 0; i < 8; ++i) {
//        results.emplace_back(
//                pool.enqueue([i] {
//                    std::cout << "hello " << i << std::endl;
//                    std::this_thread::sleep_for(std::chrono::seconds(1));
//                    std::cout << "world " << i << std::endl;
//                    return i*i;
//                })
//        );
//    }
//    pool.wait_until_empty();
//    pool.wait_until_nothing_in_flight ();
//
//    for(auto && result: results)
//        std::cout << result.get() << ' ';
//    std::cout << std::endl;





    //boost data
    auto d = boost::get_system_time().date();
    std::cout << d.year() << std::endl;
    std::cout << d.month() << std::endl;
    std::cout << d.day() << std::endl;
    d.as_special();
//    std::cout << d.day_of_week() << std::endl;
//    std::cout << d.end_of_month() << std::endl;


    //间隔时间
    boost::gregorian::date d1(2008, 1, 31);
    boost::gregorian::date d2(2008, 8, 31);
    boost::gregorian::date_duration dd = d2 - d1;
    std::cout << dd.days() << std::endl;



    //boost bind
    std::vector<int> boost_vec;
    boost_vec.push_back(2);
    boost_vec.push_back(1);
    boost_vec.push_back(3);


    // boost bind  test
    for_each(boost_vec.begin(), boost_vec.end(), boost::bind(boost_println_0, _1));
    sort(boost_vec.begin(), boost_vec.end());
    // boost
    sort(boost_vec.begin(), boost_vec.end(), boost_compare);

    // boost 传递引用  function ,arg1,arg2
    outstrm _out;
    for_each(boost_vec.begin(), boost_vec.end(), boost::bind(boost_ref, _1, boost::ref(_out)));






    //memcpy
    char myname[] = "Pierre de Fermat";
    size_t _name_length = sizeof(myname);
    /* using memcpy to copy string: */
    char _name[17];
    //void * memcpy ( void * destination, const void * source, size_t num );
    memcpy(_name, myname, _name_length);
    //void  * ptr   ,mem address
    memset(myname, 0, 13);


    char _char = 127;
    unsigned u_char = 128;
    short _short = 90;
    int *ptr_int;

    int ptr_value = 90;
    /**
     * 获取value的首地址
     */

    Pointer *ptr = new Pointer(&ptr_value);
    ptr->ptr_println();


    Base *base = new Person;
    base->say();


    boost::thread base_thread(Person::test_bind);
    base_thread.join();


    base->talk();

    base->talk();

    delete base;

    base = 0;

//    RandomHelper randomHelper;
//    for (int i = 0; i < 100; ++i) {
//        cout << randomHelper.random_real(1, 3) << endl;
//    }


    list<string> *namelist = new list<string>;
    namelist->push_back("石头哥哥");

    cout << namelist->size() << endl;
    /**
     *
     */
    for (string name:*namelist) {
        cout << name << endl;
    }


    //iterator is fan pointer
    for (list<string>::iterator iter = namelist->begin();
         iter != namelist->end();
         ++iter) {
        cout << iter->data() << endl;
    }

//    namelist->erase(begin(*namelist));//remove first element
//    namelist->clear();

    cout << namelist->size() << endl;

    delete namelist;
    namelist = nullptr;

    map<int, int> _map;
    _map[1] = 1;
    _map[2] = 2;
    _map.insert(make_pair(3, 3));

    for (auto iter = _map.begin();
         iter != _map.end();
         ++iter) {
        cout << "key:" << iter->first <<
        " value:" << iter->second << endl;
    }


    cout << endl;

    auto iter2 = std::begin(_map);
    while (iter2 != std::end(_map)) {
        cout << "key:" << iter2->first <<
        " value:" << iter2->second << endl;
        ++iter2;
    }

    map<int, int>::iterator find_iter = _map.find(1);
    if (find_iter != _map.end()) {
        cout << " ########value exist:" << find_iter->second << endl;
    }

    //
    long value = _map.erase(3);//if success ,return 1


    _map.clear();

    cout << [=](int value0)mutable { return ++value0 + value; }(10) << endl;

    cout << "Hello, World!" << endl;

    return 0;
}